package com.xmy.cultivate.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.xmy.cultivate.entity.*;
import com.xmy.cultivate.exception.CommonException;
import com.xmy.cultivate.mapper.CourseSchedulingAlwaysMapper;
import com.xmy.cultivate.mapper.CourseSchedulingMapper;
import com.xmy.cultivate.mapper.HolidayMapper;
import com.xmy.cultivate.mapper.StudentMapper;
import com.xmy.cultivate.respons.SchedulingGrade;
import com.xmy.cultivate.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xmy.cultivate.util.CommonUtil;
import com.xmy.cultivate.util.DateUtil;
import com.xmy.cultivate.util.IdWorker;
import com.xmy.cultivate.util.ResultCode;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 排课表 服务实现类
 * </p>
 *
 * @author min
 * @since 2022-07-28
 */
@Service
public class CourseSchedulingServiceImpl extends ServiceImpl<CourseSchedulingMapper, CourseScheduling> implements ICourseSchedulingService {

    @Autowired
    @Lazy
    ICourseSchedulingDetailService iCourseSchedulingDetailService;
    @Autowired
    @Lazy
    ICourseSchedulingRedoService iCourseSchedulingRedoService;

    @Autowired
    @Lazy
    IGradeService iGradeService;

    @Autowired
    @Lazy
    IOrganizationService iOrganizationService;

    @Autowired
    @Lazy
    IClassRoomService iClassRoomService;

    @Autowired
    @Lazy
    ICourseService iCourseService;

    @Autowired
    @Lazy
    IStaffService iStaffService;

    @Autowired
    @Lazy
    ISubjectsService iSubjectsService;

    @Autowired
    @Lazy
    CourseSchedulingMapper courseSchedulingMapper;

    @Autowired
    @Lazy
    StudentMapper studentMapper;

    @Autowired
    @Lazy
    IStudentGradeService iStudentGradeService;

    @Autowired
    @Lazy
    HolidayMapper holidayMapper;

    @Autowired
    @Lazy
    IDictService iDictService;

    @Autowired
    @Lazy
    CourseSchedulingAlwaysMapper courseSchedulingAlwaysMapper;

    @Autowired
    @Lazy
    ICourseSchedulingAlwaysService iCourseSchedulingAlwaysService;

    @Autowired
    @Lazy
    IdWorker idWorker;

    @Transactional
    public boolean saveTo(CourseScheduling courseScheduling) throws ParseException {

        Grade grade = iGradeService.getById(courseScheduling.getGradeId());
        if (grade == null) {
            throw new CommonException(ResultCode.GRADE_NOT);
        }

        courseScheduling.setSchoolId(grade.getSchoolId());
        courseScheduling.setCourseId(grade.getCourseId());

        if (courseScheduling.getArrangingWay() == 1) {
            String[] startTime = courseScheduling.getTimeStart().split(":");
            String[] endTime = courseScheduling.getTimeEnd().split(":");
            courseScheduling.setStartHouse(startTime[0]);
            courseScheduling.setStartHouse(startTime[1]);
            courseScheduling.setStartMinute(endTime[0]);
            courseScheduling.setEndMinute(endTime[1]);
        }

        this.save(courseScheduling);

        //排课方式
        Integer arrangingWay = courseScheduling.getArrangingWay();
        //自由排课
        if (arrangingWay == 1) {

            String attendClassDates = courseScheduling.getAttendClassDates();
            if (StringUtils.isBlank(attendClassDates)) {
                throw new CommonException(ResultCode.AttendClassDateNotNull);
            }

            Organization shooleInfo = iOrganizationService.getById(courseScheduling.getSchoolId());
            if (shooleInfo == null) {
                throw new CommonException(ResultCode.SchoolNotNull);
            }
            ClassRoom classRoom = iClassRoomService.getById(courseScheduling.getClassRoomId());
            if (classRoom == null) {
                throw new CommonException(ResultCode.ClassRoomNotNull);
            }
            Course course = iCourseService.getById(courseScheduling.getCourseId());
            if (course == null) {
                throw new CommonException(ResultCode.CourseNotNull);
            }
            Staff teacher = iStaffService.getById(courseScheduling.getTeacherId());
            if (teacher == null) {
                throw new CommonException(ResultCode.TeacerNo);
            }

            UpdateWrapper<Grade> gradeUpdateWrapper = new UpdateWrapper<>();
            gradeUpdateWrapper.eq("id", grade.getId()).set("teacher_id", teacher.getId()).set("class_room_id", classRoom.getId());
            iGradeService.update(null, gradeUpdateWrapper);

            Staff assistant = iStaffService.getById(courseScheduling.getAssistantId());
            Subjects subjects = iSubjectsService.getById(course.getSubjectsId());

            //自由排课
            List<CourseSchedulingDetail> courseSchedulingDetailList = new ArrayList<>();
            List<String> datesList = Arrays.asList(attendClassDates.split(","));
            Iterator<String> iterator = datesList.iterator();
            Integer lessonNum = 0;
            while (iterator.hasNext()) {
                String date = iterator.next();
                LocalDate nextDate = LocalDate.parse(date);
                Long gradeId = courseScheduling.getGradeId();
                LocalDateTime startDateTime = DateUtil.StrToDateTime(date + "T" + courseScheduling.getTimeStart() + ":00");
                LocalDateTime endDateTime = DateUtil.StrToDateTime(date + "T" + courseScheduling.getTimeEnd() + ":00");
                QueryWrapper<CourseSchedulingDetail> courseSchedulingDetailQueryWrapper = new QueryWrapper<>();
                courseSchedulingDetailQueryWrapper.eq("grade_id", gradeId);
                courseSchedulingDetailQueryWrapper.eq("start_date_time", startDateTime);
                courseSchedulingDetailQueryWrapper.eq("end_date_time", endDateTime);

                CourseSchedulingDetail courseSchedulingDetail = new CourseSchedulingDetail();

                //非添加班级时自动排课，这里添加课次
                if (grade.getIsAutoScheduling().equals(0)){
                    if (lessonNum.equals(0)){
                        lessonNum = iCourseSchedulingDetailService.getNextLessonNum(grade.getId(),nextDate);
                    }else {
                        lessonNum++;
                    }
                    courseSchedulingDetail.setLessonNum(lessonNum);
                }

                Long count = iCourseSchedulingDetailService.count(courseSchedulingDetailQueryWrapper);
                if (count > 0) {
                    continue;
                }

                courseSchedulingDetail.setCourseSchedulingId(courseScheduling.getId());
                courseSchedulingDetail.setSchoolDate(DateUtil.StrToDate(date));
                courseSchedulingDetail.setTimeStart(courseScheduling.getTimeStart());
                courseSchedulingDetail.setTimeEnd(courseScheduling.getTimeEnd());

                courseSchedulingDetail.setStartDateTime(startDateTime);
                courseSchedulingDetail.setEndDateTime(endDateTime);
                courseSchedulingDetail.setArrangingWay(courseScheduling.getArrangingWay());

                //校区
                courseSchedulingDetail.setSchoolId(grade.getSchoolId());
                courseSchedulingDetail.setSchoolName(shooleInfo.getName());
                //班级
                courseSchedulingDetail.setGradeId(gradeId);
                courseSchedulingDetail.setGradeName(grade.getName());
                //老师
                courseSchedulingDetail.setTeacherId(courseScheduling.getTeacherId());
                courseSchedulingDetail.setTeacherName(teacher.getName());
                //助教
                courseSchedulingDetail.setAssistantId(courseScheduling.getAssistantId());
                if (assistant != null) {
                    courseSchedulingDetail.setAssistantName(assistant.getName());
                }

                //教室
                courseSchedulingDetail.setClassRoomId(courseScheduling.getClassRoomId());
                courseSchedulingDetail.setClassRoomName(classRoom.getName());
                //科目
                courseSchedulingDetail.setSubjectsId(course.getSubjectsId());
                if (subjects != null) {
                    courseSchedulingDetail.setSubjectsName(subjects.getName());
                }

                //课程
                courseSchedulingDetail.setCourseId(grade.getCourseId());
                courseSchedulingDetail.setCourseName(course.getName());

                courseSchedulingDetail.setYearPart(grade.getYearPart());
                courseSchedulingDetail.setQuarter(course.getQuarterNum());

                courseSchedulingDetail.setLessonType(grade.getLessonType());

                courseSchedulingDetailList.add(courseSchedulingDetail);
                //System.out.print(date);
            }
            if (courseSchedulingDetailList.size() > 0) {
                iCourseSchedulingDetailService.saveBatch(courseSchedulingDetailList, courseSchedulingDetailList.size());
            }

        } else if (arrangingWay == 2) {
            //重复排课
            List<CourseSchedulingRedo> courseSchedulingRedoList = courseScheduling.getRedoList();
            Iterator<CourseSchedulingRedo> iterator = courseSchedulingRedoList.iterator();
            while (iterator.hasNext()) {
                //自由排课
                List<CourseSchedulingDetail> courseSchedulingDetailList = new ArrayList<>();

                CourseSchedulingRedo courseSchedulingRedo = iterator.next();
                ////System.out.print(courseSchedulingRedo);

                courseSchedulingRedo.setSchoolId(grade.getSchoolId());
                courseSchedulingRedo.setCourseId(grade.getCourseId());
                courseSchedulingRedo.setGradeId(courseScheduling.getGradeId());
                Organization shooleInfo = iOrganizationService.getById(courseSchedulingRedo.getSchoolId());
                if (shooleInfo == null) {
                    throw new CommonException(ResultCode.SchoolNotNull);
                }
                ClassRoom classRoom = iClassRoomService.getById(courseSchedulingRedo.getClassRoomId());
                if (classRoom == null) {
                    throw new CommonException(ResultCode.ClassRoomNotNull);
                }
                Course course = iCourseService.getById(courseSchedulingRedo.getCourseId());
                if (course == null) {
                    throw new CommonException(ResultCode.CourseNotNull);
                }
                Staff teacher = iStaffService.getById(courseSchedulingRedo.getTeacherId());
                if (teacher == null) {
                    throw new CommonException(ResultCode.TeacerNo);
                }

                Staff assistant = iStaffService.getById(courseSchedulingRedo.getAssistantId());
                Subjects subjects = iSubjectsService.getById(course.getSubjectsId());


                courseSchedulingRedo.setCourseSchedulingId(courseScheduling.getId());
                //courseSchedulingRedo.setGradeId(courseScheduling.getGradeId());
                courseSchedulingRedo.setArrangingWay(courseScheduling.getArrangingWay());

                String[] strartTime = courseSchedulingRedo.getTimeStart().split(":");
                String[] endTime = courseSchedulingRedo.getTimeEnd().split(":");
                courseSchedulingRedo.setStartHouse(strartTime[0]);
                courseSchedulingRedo.setStartHouse(strartTime[1]);
                courseSchedulingRedo.setStartMinute(endTime[0]);
                courseSchedulingRedo.setEndMinute(endTime[1]);

                List<Integer> weekDates = courseSchedulingRedo.getWeekDatesList();
                if (weekDates.size() > 0) {
                    String weekDatesStr = weekDates.stream().map(Object::toString).collect(Collectors.joining(","));
                    courseSchedulingRedo.setWeekDates(weekDatesStr);
                }

                iCourseSchedulingRedoService.save(courseSchedulingRedo);
                if (courseSchedulingRedo.getEndMode() == 1) {
                    //按日期

                    Long diffDateNum = DateUtil.diffDays(courseSchedulingRedo.getStartDate(), courseSchedulingRedo.getEndDate());
                    //System.out.println();
                    //System.out.print("diffDateNum:"+diffDateNum);
                    Integer lessonNum = 0;
                    for (Integer i = 0; i <= diffDateNum; i++) {
                        //添加天数
                        LocalDate nowDate = courseSchedulingRedo.getStartDate().plusDays(i);
                        //System.out.println();
                        //System.out.print("nowDate:"+nowDate);
                        Integer weekIndex = DateUtil.getWeekIndex(nowDate);
                        //System.out.println();
                        //System.out.print("weekIndex:"+weekIndex);
                        if (weekDates.contains(weekIndex)) {
                            //存在
                            CourseSchedulingDetail courseSchedulingDetail = new CourseSchedulingDetail();
                            courseSchedulingDetail.setCourseSchedulingId(courseScheduling.getId());
                            courseSchedulingDetail.setSchoolDate(nowDate);
                            courseSchedulingDetail.setTimeStart(courseSchedulingRedo.getTimeStart());
                            courseSchedulingDetail.setTimeEnd(courseSchedulingRedo.getTimeEnd());

                            LocalDateTime startDateTime = DateUtil.StrToDateTime(nowDate + "T" + courseSchedulingRedo.getTimeStart() + ":00");
                            LocalDateTime endDateTime = DateUtil.StrToDateTime(nowDate + "T" + courseSchedulingRedo.getTimeEnd() + ":00");

                            Long gradeId = courseScheduling.getGradeId();
                            QueryWrapper<CourseSchedulingDetail> courseSchedulingDetailQueryWrapper = new QueryWrapper<>();
                            courseSchedulingDetailQueryWrapper.eq("grade_id", gradeId);
                            courseSchedulingDetailQueryWrapper.eq("start_date_time", startDateTime);
                            courseSchedulingDetailQueryWrapper.eq("end_date_time", endDateTime);

                            //非添加班级时自动排课，这里添加课次
                            if (grade.getIsAutoScheduling().equals(0)){
                                if (lessonNum.equals(0)){
                                    lessonNum = iCourseSchedulingDetailService.getNextLessonNum(grade.getId(),nowDate);
                                }else {
                                    lessonNum++;
                                }
                                courseSchedulingDetail.setLessonNum(lessonNum);
                            }
                            Long count = iCourseSchedulingDetailService.count(courseSchedulingDetailQueryWrapper);
                            if (count > 0) {
                                continue;
                            }


                            courseSchedulingDetail.setStartDateTime(startDateTime);
                            courseSchedulingDetail.setEndDateTime(endDateTime);

                            courseSchedulingDetail.setArrangingWay(courseScheduling.getArrangingWay());//排课方式

                            //校区
                            courseSchedulingDetail.setSchoolId(grade.getSchoolId());
                            courseSchedulingDetail.setSchoolName(shooleInfo.getName());
                            //班级
                            courseSchedulingDetail.setGradeId(courseSchedulingRedo.getGradeId());
                            courseSchedulingDetail.setGradeName(grade.getName());
                            //老师
                            courseSchedulingDetail.setTeacherId(courseSchedulingRedo.getTeacherId());
                            courseSchedulingDetail.setTeacherName(teacher.getName());
                            //助教
                            courseSchedulingDetail.setAssistantId(courseSchedulingRedo.getAssistantId());
                            if (assistant != null) {
                                courseSchedulingDetail.setAssistantName(assistant.getName());
                            }

                            //教室
                            courseSchedulingDetail.setClassRoomId(courseSchedulingRedo.getClassRoomId());
                            courseSchedulingDetail.setClassRoomName(classRoom.getName());
                            //科目
                            courseSchedulingDetail.setSubjectsId(course.getSubjectsId());
                            if (subjects != null) {
                                courseSchedulingDetail.setSubjectsName(subjects.getName());
                            }

                            courseSchedulingDetail.setYearPart(grade.getYearPart());
                            courseSchedulingDetail.setQuarter(course.getQuarterNum());

                            //课程
                            courseSchedulingDetail.setCourseId(grade.getCourseId());
                            courseSchedulingDetail.setCourseName(course.getName());
                            courseSchedulingDetail.setLessonType(grade.getLessonType());
                            courseSchedulingDetailList.add(courseSchedulingDetail);
                        } else {
                            //System.out.println();
                            //System.out.print("dates.contains，不存在");
                        }
                    }
                } else if (courseSchedulingRedo.getEndMode() == 2) {
                    //按期数
                    Integer count = courseSchedulingRedo.getExpectNum();
                    Integer i = 0;
                    boolean flag = true;
                    Integer lessonNum = 0;
                    while (flag) {
                        LocalDate nowDate = courseSchedulingRedo.getStartDate().plusDays(i);
                        Integer weekIndex = DateUtil.getWeekIndex(nowDate);
                        if (weekDates.contains(weekIndex)) {
                            //存在
                            CourseSchedulingDetail courseSchedulingDetail = new CourseSchedulingDetail();

                            courseSchedulingDetail.setCourseSchedulingId(courseScheduling.getId());
                            courseSchedulingDetail.setSchoolDate(nowDate);
                            courseSchedulingDetail.setTimeStart(courseSchedulingRedo.getTimeStart());
                            courseSchedulingDetail.setTimeEnd(courseSchedulingRedo.getTimeEnd());

                            LocalDateTime startDateTime = DateUtil.StrToDateTime(nowDate + "T" + courseSchedulingRedo.getTimeStart() + ":00");
                            LocalDateTime endDateTime = DateUtil.StrToDateTime(nowDate + "T" + courseSchedulingRedo.getTimeEnd() + ":00");

                            courseSchedulingDetail.setStartDateTime(startDateTime);
                            courseSchedulingDetail.setEndDateTime(endDateTime);

                            Long gradeId = courseScheduling.getGradeId();
                            QueryWrapper<CourseSchedulingDetail> courseSchedulingDetailQueryWrapper = new QueryWrapper<>();
                            courseSchedulingDetailQueryWrapper.eq("grade_id", gradeId);
                            courseSchedulingDetailQueryWrapper.eq("start_date_time", startDateTime);
                            courseSchedulingDetailQueryWrapper.eq("end_date_time", endDateTime);

                            //非添加班级时自动排课，这里添加课次
                            if (grade.getIsAutoScheduling().equals(0)){
                                if (lessonNum.equals(0)){
                                    lessonNum = iCourseSchedulingDetailService.getNextLessonNum(grade.getId(),nowDate);
                                }else {
                                    lessonNum ++;
                                }
                                courseSchedulingDetail.setLessonNum(lessonNum);
                            }


                            Long schedulingCount = iCourseSchedulingDetailService.count(courseSchedulingDetailQueryWrapper);
                            if (schedulingCount > 0) {
                                continue;
                            }



                            courseSchedulingDetail.setArrangingWay(courseScheduling.getArrangingWay());//排课方式
                            courseSchedulingDetail.setSubjectsId(courseSchedulingRedo.getSubjectsId());

                            //校区
                            courseSchedulingDetail.setSchoolId(grade.getSchoolId());
                            courseSchedulingDetail.setSchoolName(shooleInfo.getName());
                            //班级
                            courseSchedulingDetail.setGradeId(grade.getId());
                            courseSchedulingDetail.setGradeName(grade.getName());
                            //老师
                            courseSchedulingDetail.setTeacherId(courseSchedulingRedo.getTeacherId());
                            courseSchedulingDetail.setTeacherName(teacher.getName());
                            //助教
                            courseSchedulingDetail.setAssistantId(courseSchedulingRedo.getAssistantId());
                            if (assistant != null) {
                                courseSchedulingDetail.setAssistantName(assistant.getName());
                            }

                            //教室
                            courseSchedulingDetail.setClassRoomId(courseSchedulingRedo.getClassRoomId());
                            courseSchedulingDetail.setClassRoomName(classRoom.getName());
                            //科目
                            courseSchedulingDetail.setSubjectsId(course.getSubjectsId());
                            if (subjects != null) {
                                courseSchedulingDetail.setSubjectsName(subjects.getName());
                            }

                            courseSchedulingDetail.setYearPart(grade.getYearPart());
                            courseSchedulingDetail.setQuarter(course.getQuarterNum());

                            //课程
                            courseSchedulingDetail.setCourseId(grade.getCourseId());
                            courseSchedulingDetail.setCourseName(course.getName());
                            courseSchedulingDetail.setLessonType(grade.getLessonType());

                            courseSchedulingDetailList.add(courseSchedulingDetail);
                            count--;
                        }
                        if (count == 0) {
                            flag = false;
                        }
                        i++;
                    }
                }
                if (courseSchedulingDetailList.size() > 0) {
                    iCourseSchedulingDetailService.saveBatch(courseSchedulingDetailList, courseSchedulingDetailList.size());
                }
            }
        }


        return true;
    }

    @Override
    public List<Student> getStudentForSchedulingGrade(String gradeId, String schedulingDetailId,String studentName) {
        List<Student> studentList = courseSchedulingMapper.getStudentForSchedulingGrade(Long.parseLong(gradeId), Long.parseLong(schedulingDetailId),studentName);
        for (Student student : studentList) {
            Long schoolId = student.getSchoolId();
            Student studentNew = studentMapper.selectById(student.getId());
            if (studentNew != null) {
                Integer couseType = student.getCourseType();
                BeanUtils.copyProperties(studentNew, student);
                student.setCourseType(couseType);
            }
            student.setSchoolId(schoolId);

            String state = iStudentGradeService.studentAtGradeState(Long.parseLong(gradeId), student.getId(), 1);

            student.setState(state);
        }

        return studentList;
    }


    /**
     * 自动排课
     * @param gradeId
     * @param startDateParam 开始时间,不填写为班级开始时间，（班级修改时填写）
     * @return
     * @throws ParseException
     */
    @Override
    @Transactional
    public Integer autoScheduling(Long gradeId, LocalDate startDateParam) throws ParseException {

        Grade grade = iGradeService.getById(gradeId);
        if (grade == null)
            return 0;
        Integer isVacation = grade.getIsVacation();
        String weekDates = grade.getWeekDates();
        LocalDate startDate = this.getOpenDate(grade);

        if (startDateParam != null){
            //是否已经记上课过
            Integer count = iCourseSchedulingDetailService.getSchedulingCountForRecord(gradeId);
            if (count>0){
                //startDate = startDateParam;
            }
        }
        LocalDate dateNow = LocalDate.now();
        LocalDateTime dateTime = LocalDateTime.now().withNano(0);
        //* 删除当前时间之后的排课
        iCourseSchedulingDetailService.deleteForGradeId(gradeId,dateTime);
        LocalDate endDate = courseSchedulingAlwaysMapper.getMaxEndDate(grade.getYearPart(),grade.getQuarterNum(),CommonUtil.getGradeSection(grade.getYearClassId().getKey()));
        if (endDate == null){
            endDate = grade.getEndDate();
        }else {
            if (endDate.isBefore(grade.getEndDate())){
                endDate = grade.getEndDate();
            }
        }

        //暑假班智能课与刷题班结束时间往后1天
        if (grade.getQuarterNum().equals(3) && !grade.getLessonType().equals(1)){
            //endDate = endDate.plusDays(1);
        }

        Organization organization = iOrganizationService.getById(grade.getSchoolId());
        Course course = iCourseService.getById(grade.getCourseId());
        Staff staff = iStaffService.getById(grade.getTeacherId());
        ClassRoom classRoom = iClassRoomService.getById(grade.getClassRoomId());

        String schoolName = organization.getName();
        String courseName = course.getName();
        String teacherName = staff.getName();
        String roomName = classRoom != null ? classRoom.getName() : "";
        Long subjectsId = course.getSubjectsId();
        String subjectsName = CommonUtil.getSubjectsNameForId(Integer.parseInt(subjectsId.toString()));
        Integer quarterNum = course.getQuarterNum();
        Long courseSchedulingId = idWorker.nextId();

        Integer schedulintCount = 0;
        Integer lessonNum = 1;

        //A天或者B天
        LocalDate nextDate = startDate;

        boolean isNext = true;
        //是否假期，0否，1是（假期指的是：寒假、暑假）
        if (isVacation.equals(1)) {
            Integer plusDay = 1;//寒假班加1，暑假班加2
            if (grade.getQuarterNum().equals(3)){
                plusDay = 2;//暑假班初中加2
            }
            while (isNext) {
                //是否存在节假日
                Integer isAt = holidayMapper.getIsAt(nextDate,1);
                if (isAt > 0) {
                    nextDate = nextDate.plusDays(plusDay);//加
                    continue;
                }
                boolean rs = this.addSchedulingForGrade(grade, schoolName, courseName, teacherName, roomName, subjectsId, subjectsName, quarterNum, nextDate, courseSchedulingId,lessonNum);
                if (rs) {
                    schedulintCount++;
                }
                nextDate = nextDate.plusDays(plusDay);//加
                if (nextDate.isAfter(endDate)) {
                    isNext = false;
                }
                lessonNum++;
            }

        } else {
            while (isNext) {
                Integer isAt = holidayMapper.getIsAt(nextDate,1);
                if (isAt > 0) {
                    //存在节假日
                    nextDate = nextDate.plusDays(1);//加1
                    continue;
                }
                Integer weekIndex = DateUtil.getWeekIndex(nextDate);//获取出当前属于星期几
                String[] stringArray = weekDates.split(",");
                List<Integer> weekDateList = new ArrayList<>();
                for (String str : stringArray) {
                    Integer number = Integer.parseInt(str);
                    weekDateList.add(number);
                }
                if (weekDateList.contains(weekIndex)) {
                    boolean rs = this.addSchedulingForGrade(grade, schoolName, courseName, teacherName, roomName, subjectsId, subjectsName, quarterNum, nextDate, courseSchedulingId,lessonNum);
                    if (rs) {
                        schedulintCount++;
                    }
                }
                nextDate = nextDate.plusDays(1);//加1
                if (nextDate.isAfter(endDate)) {
                    isNext = false;
                }
                lessonNum++;
            }
        }
        return schedulintCount;
    }


    @Override
    public LocalDate getOpenDate(Grade grade){
        Course course = iCourseService.getById(grade.getCourseId());
        //前端调整了，防止已经存在的页面有缓存，添加下面代码
        Integer gradeSection = CommonUtil.getGradeSectionForYearClassId(course.getYearClassId().getKey());
        LocalDate openDate = iCourseSchedulingAlwaysService.getStartDate(grade.getYearPart(), course.getQuarterNum(), gradeSection, null);
        if (grade.getWeekDates().equals("B")) {
            openDate = openDate.plusDays(1);
        }
        if (grade.getQuarterNum().equals(3) && !grade.getLessonType().equals(1)){
            //智能或者刷题班
            //openDate = openDate.plusDays(1);
        }

        return openDate;
    }



    @Async("onlineAsync")
    @Override
    public void addOtherDate(Integer yearPart,Integer quarterNum,Integer lessonType,String startDateParam,String endDateParam) throws ParseException {
        QueryWrapper<Grade> gradeQueryWrapper = new QueryWrapper<>();
        gradeQueryWrapper.eq("year_part", yearPart);
        gradeQueryWrapper.eq("quarter_num", quarterNum);
        gradeQueryWrapper.eq("status", 1);
        //gradeQueryWrapper.eq("year_class_id", 9);
//        gradeQueryWrapper.in("lesson_type", 2, 3);
        gradeQueryWrapper.eq("lesson_type", lessonType);

        List<Grade> gradeList = iGradeService.list(gradeQueryWrapper);
        Integer i = 1;
        for (Grade grade : gradeList) {
            LocalDate statDate = LocalDate.parse(startDateParam);//"2024-06-22"
            //LocalDate statDate = grade.getEndDate().plusDays(1);
            LocalDate endDate = LocalDate.parse(endDateParam);//"2024-07-07"
            this.autoSchedulingForDate(grade.getId(), statDate, endDate);
            i++;
            //log.info("size:"+gradeList.size()+"i:"+i);
        }
    }



    /**
     *
     * @param gradeId
     * @param startDate
     * @param endDate
     * @return
     * @throws ParseException
     */
    @Override
    @Transactional
    public Integer autoSchedulingForDate(Long gradeId, LocalDate startDate,LocalDate endDate) throws ParseException {

        Grade grade = iGradeService.getById(gradeId);
        if (grade == null)
            return 0;
        Integer isVacation = grade.getIsVacation();
        String weekDates = grade.getWeekDates();
        //* 删除当前时间之后的排课
        //iCourseSchedulingDetailService.deleteForGradeId(gradeId,startDate);

        Organization organization = iOrganizationService.getById(grade.getSchoolId());
        Course course = iCourseService.getById(grade.getCourseId());
        Staff staff = iStaffService.getById(grade.getTeacherId());
        ClassRoom classRoom = iClassRoomService.getById(grade.getClassRoomId());

        String schoolName = organization.getName();
        String courseName = course.getName();
        String teacherName = staff.getName();
        String roomName = classRoom != null ? classRoom.getName() : "";
        Long subjectsId = course.getSubjectsId();
        String subjectsName = CommonUtil.getSubjectsNameForId(Integer.parseInt(subjectsId.toString()));
        Integer quarterNum = course.getQuarterNum();
        Long courseSchedulingId = idWorker.nextId();

        Integer schedulintCount = 0;

        Integer lessonNum = 1;


        //A天或者B天
        LocalDate nextDate = startDate;
        boolean isNext = true;
        //是否假期，0否，1是（假期指的是：寒假、暑假）
        if (isVacation.equals(1)) {
            Integer plusDay = 1;//寒假班加1，暑假班加2
            if (grade.getQuarterNum().equals(3)){
                plusDay = 2;//暑假班加2
            }

            if (weekDates.equals("B")) {
                nextDate = nextDate.plusDays(1);//B天开始日期加1
            }
            while (isNext) {
                //是否存在节假日
                Integer isAt = holidayMapper.getIsAt(nextDate,1);
                if (isAt > 0) {
                    nextDate = nextDate.plusDays(plusDay);//加
                    continue;
                }
                boolean rs = this.addSchedulingForGrade(grade, schoolName, courseName, teacherName, roomName, subjectsId, subjectsName, quarterNum, nextDate, courseSchedulingId,lessonNum);
                if (rs) {
                    schedulintCount++;
                }
                nextDate = nextDate.plusDays(plusDay);//加
                if (nextDate.isAfter(endDate)) {
                    isNext = false;
                }
                lessonNum++;
            }

        } else {
            while (isNext) {
                Integer isAt = holidayMapper.getIsAt(nextDate,1);
                if (isAt > 0) {
                    //存在节假日
                    nextDate = nextDate.plusDays(1);//加1
                    continue;
                }
                Integer weekIndex = DateUtil.getWeekIndex(nextDate);//获取出当前属于星期几
                String[] stringArray = weekDates.split(",");
                List<Integer> weekDateList = new ArrayList<>();
                for (String str : stringArray) {
                    Integer number = Integer.parseInt(str);
                    weekDateList.add(number);
                }
                if (weekDateList.contains(weekIndex)) {
                    boolean rs = this.addSchedulingForGrade(grade, schoolName, courseName, teacherName, roomName, subjectsId, subjectsName, quarterNum, nextDate, courseSchedulingId,lessonNum);
                    if (rs) {
                        schedulintCount++;
                    }
                }
                nextDate = nextDate.plusDays(1);//加1
                if (nextDate.isAfter(endDate)) {
                    isNext = false;
                }
                lessonNum++;
            }
        }
        return schedulintCount;
    }

    /**
     *
     * @param grade
     * @param schoolName
     * @param courseName
     * @param teacherName
     * @param roomName
     * @param subjectsId
     * @param subjectsName
     * @param quarterNum
     * @param nextDate
     * @param courseSchedulingId
     * @param lessonNumParam 课次
     * @return
     * @throws ParseException
     */
    public boolean addSchedulingForGrade(Grade grade, String schoolName, String courseName, String teacherName, String roomName, Long subjectsId, String subjectsName, Integer quarterNum, LocalDate nextDate, Long courseSchedulingId,Integer lessonNumParam) throws ParseException {

        /**
         * 是否存在排课信息
         */
        Long isAt = iCourseSchedulingDetailService.getIsAtForDate(grade.getId(), nextDate);
        if (isAt > 0) {
            return false;
        }

        Integer lessonNum = null;
        CourseSchedulingAlways courseSchedulingAlways = courseSchedulingAlwaysMapper.getOneForYearAndDate(grade.getYearPart(),grade.getQuarterNum(),CommonUtil.getGradeSection(grade.getYearClassId().getKey()),nextDate.toString());
        if (courseSchedulingAlways != null){
            lessonNum = courseSchedulingAlways.getNum();
        }
        Integer isVacation = grade.getIsVacation();
        //是否假期，0否，1是（假期指的是：寒假、暑假）
        if (isVacation.equals(1)) {
            if (grade.getQuarterNum().equals(3)){
                //由于暑假高中会存在两期，因此课次不按校历获取
                if (grade.getYearClassId().getKey() > 9){
                    //lessonNum = null;
                }
                //暑假班，智能课与刷题班课
                if (!grade.getLessonType().equals(1)){
                    lessonNum = null;
                }
            }
        }

        if (lessonNum == null){
            lessonNum = iCourseSchedulingDetailService.getNextLessonNum(grade.getId(),nextDate);
        }else {
            Integer lessonNumNext = iCourseSchedulingDetailService.getNextLessonNum(grade.getId(),nextDate);
            if (lessonNum > lessonNumNext){
                lessonNum = lessonNumNext;
            }
        }

        if (lessonNum!=null){
            isAt = iCourseSchedulingDetailService.getIsAt(grade.getId(), lessonNum);
            if (isAt > 0) {
                return false;
            }
        }

        CourseSchedulingDetail courseSchedulingDetail = new CourseSchedulingDetail();
        Long id = idWorker.nextId();
        courseSchedulingDetail.setId(id);
        courseSchedulingDetail.setSchoolId(grade.getSchoolId());
        courseSchedulingDetail.setCourseSchedulingId(courseSchedulingId);

        courseSchedulingDetail.setLessonNum(lessonNum);//课次
        courseSchedulingDetail.setSchoolName(schoolName);
        courseSchedulingDetail.setGradeId(grade.getId());
        courseSchedulingDetail.setGradeName(grade.getName());
        courseSchedulingDetail.setCourseId(grade.getCourseId());
        courseSchedulingDetail.setCourseName(courseName);
        courseSchedulingDetail.setSchoolDate(nextDate);
        LocalDateTime startDateTime = DateUtil.StrToDateTime(nextDate + "T" + grade.getTimeStart() + ":00");
        LocalDateTime endDateTime = DateUtil.StrToDateTime(nextDate + "T" + grade.getTimeEnd() + ":00");
        courseSchedulingDetail.setStartDateTime(startDateTime);
        courseSchedulingDetail.setEndDateTime(endDateTime);
        courseSchedulingDetail.setTimeStart(grade.getTimeStart());
        courseSchedulingDetail.setTimeEnd(grade.getTimeEnd());
        courseSchedulingDetail.setArrangingWay(3);
        courseSchedulingDetail.setTeacherId(grade.getTeacherId());
        courseSchedulingDetail.setTeacherName(teacherName);
        courseSchedulingDetail.setAssistantId(grade.getHelpTeacherId());
        courseSchedulingDetail.setClassRoomId(grade.getClassRoomId());
        courseSchedulingDetail.setClassRoomName(roomName);
        courseSchedulingDetail.setSubjectsId(subjectsId);
        courseSchedulingDetail.setSubjectsName(subjectsName);
        courseSchedulingDetail.setYearPart(grade.getYearPart());
        courseSchedulingDetail.setQuarter(quarterNum);
        courseSchedulingDetail.setLessonType(grade.getLessonType());
        iCourseSchedulingDetailService.save(courseSchedulingDetail);
        return true;
    }


    /**
     * 学期A
     *
     * @param yearPart
     * @param quarterNum
     * @param schoolId
     * @return
     */
    public List<Map<String, Object>> getSchedulingTermA(Integer yearPart, Integer quarterNum, Long schoolId, Integer subjectsId,Integer lessonType,Integer sourseLeve,Long adminId) {
        //是否假期，0否，1是（假期指的是：寒假、暑假）
        Integer IsVacation = iDictService.getIsVacation(quarterNum);
        String schedulingType = "";

        /**
         * 班级上课时间
         */
        List<SchedulingGrade> gradeList = iGradeService.getGradeListForScheduling(schoolId, subjectsId, yearPart, quarterNum, null,lessonType,sourseLeve,adminId);

        /**
         * 教室
         */
        List<ClassRoom> classRoomList = iClassRoomService.getGradeClassRoomList(schoolId, yearPart, quarterNum,lessonType,sourseLeve,adminId);

        String[] weeks = {"", "周一", "周二", "周三", "周四", "周五"};
        String column = "column";

        Map<String, Object> dynamicColumns = new LinkedHashMap<>();
        Integer i = 0;
        List<Map<String, Object>> mapList = new ArrayList<>();

        for (ClassRoom classRoom : classRoomList) {
            dynamicColumns = new LinkedHashMap<>();
            i = 0;
            for (String weeksName : weeks) {
                String weeksColumn = column + i;
                if (i.equals(0)) {
                    dynamicColumns.put(weeksColumn, classRoom.getName());

                } else {
                    List<SchedulingGrade> mapGradeList = new ArrayList<>();
                    String gradeName = "";
                    for (SchedulingGrade grade : gradeList) {
                        if (grade.getClassRoomId() != null && classRoom.getId() != null && grade.getWeekDates() != null) {
                            if (grade.getClassRoomId().equals(classRoom.getId()) && grade.getWeekDates().equals(i.toString())) {
                                mapGradeList.add(grade);
                                weeks[0] = grade.getSchoolTime();
                            }
                        }
                    }
                    dynamicColumns.put(weeksColumn, mapGradeList);
                    //dynamicColumns.put(weeksColumn,gradeName);
                }
                //dynamicColumns.put(weeksColumn[i], classRoom.getName());
                i++;
            }
            mapList.add(dynamicColumns);

        }
        Map<String, Object> map = new HashMap<>();
        map.put("headList", weeks);
        map.put("mapList", mapList);

        List<Map<String, Object>> rsMapList = new ArrayList<>();
        rsMapList.add(map);
        return rsMapList;
    }



    /**
     * 学期B
     *
     * @param yearPart
     * @param quarterNum
     * @param schoolId
     * @return
     */
    public List<Map<String, Object>> getSchedulingTermB(Integer yearPart, Integer quarterNum, Long schoolId, Integer subjectsId,Integer lessonType,Integer sourseLeve,Long adminId) {
        //是否假期，0否，1是（假期指的是：寒假、暑假）
        Integer IsVacation = iDictService.getIsVacation(quarterNum);
        String schedulingType = "";
        List<ClassRoom> classRoomList = iClassRoomService.getGradeClassRoomList(schoolId, yearPart, quarterNum,lessonType,sourseLeve,adminId);

        String[] weeks = {"周六", "周日"};


        List<Map<String, Object>> rsMapList = new ArrayList<>();
        for (String weekName : weeks) {
            String weekDates = "6";
            if (weekName.equals("周日")) {
                weekDates = "0";
            }
            List<SchedulingGrade> gradeList = iGradeService.getGradeListForScheduling(schoolId, subjectsId, yearPart, quarterNum, weekDates,lessonType,sourseLeve,adminId);

            String column = "column";
            List<String> schoolTimeList = iGradeService.getSchoolTimeList(schoolId, yearPart, quarterNum, null,lessonType);
            schoolTimeList.add(0, weekName);

            Map<String, Object> dynamicColumns = new LinkedHashMap<>();
            Integer i = 0;
            List<Map<String, Object>> mapList = new ArrayList<>();
            for (ClassRoom classRoom : classRoomList) {
                dynamicColumns = new LinkedHashMap<>();
                i = 0;
                for (String schoolTime : schoolTimeList) {
                    String weeksColumn = column + i;
                    if (i.equals(0)) {
                        dynamicColumns.put(weeksColumn, classRoom.getName());
                    } else {
                        List<SchedulingGrade> mapGradeList = new ArrayList<>();
                        String gradeName = "";
                        for (SchedulingGrade grade : gradeList) {
                            if (grade.getClassRoomId() != null && classRoom.getId() != null && grade.getWeekDates() != null) {
                                if (grade.getClassRoomId().equals(classRoom.getId()) && schoolTime.equals(grade.getSchoolTime())) {
                                    //Map<String,Object> gradeMap = new HashMap<>();
                                    //gradeMap.put("grade",grade);
                                    mapGradeList.add(grade);
                                    //gradeName += grade.getName()+",";
                                }
                            }
                        }
                        dynamicColumns.put(weeksColumn, mapGradeList);
                        //dynamicColumns.put(weeksColumn,gradeName);
                    }
                    i++;
                }
                mapList.add(dynamicColumns);
            }

            Map<String, Object> map = new HashMap<>();
            map.put("headList", schoolTimeList);
            map.put("mapList", mapList);
            rsMapList.add(map);
        }
        return rsMapList;
    }

    /**
     * 假期
     *
     * @param yearPart
     * @param quarterNum
     * @param schoolId
     * @return
     */
    public List<Map<String, Object>> getSchedulingVacation(Integer yearPart, Integer quarterNum, Long schoolId, Integer subjectsId,Integer lessonType,Integer sourseLeve,Long adminId) {
        //是否假期，0否，1是（假期指的是：寒假、暑假）
        Integer IsVacation = iDictService.getIsVacation(quarterNum);
        String schedulingType = "";
        List<ClassRoom> classRoomList = iClassRoomService.getGradeClassRoomList(schoolId, yearPart, quarterNum,lessonType,sourseLeve,adminId);

        String[] weeks = {"A天", "B天"};


        List<Map<String, Object>> rsMapList = new ArrayList<>();
        for (String weekName : weeks) {
            String weekDates = "A";
            if (weekName.equals("B天")) {
                weekDates = "B";
            }
            List<SchedulingGrade> gradeList = iGradeService.getGradeListForScheduling(schoolId, subjectsId, yearPart, quarterNum, weekDates,lessonType,sourseLeve,adminId);

            String column = "column";
            List<String> schoolTimeList = iGradeService.getSchoolTimeList(schoolId, yearPart, quarterNum, null,lessonType);
            schoolTimeList.add(0, weekName);

            Map<String, Object> dynamicColumns = new LinkedHashMap<>();
            Integer i = 0;
            List<Map<String, Object>> mapList = new ArrayList<>();
            for (ClassRoom classRoom : classRoomList) {
                dynamicColumns = new LinkedHashMap<>();
                i = 0;
                for (String schoolTime : schoolTimeList) {
                    String weeksColumn = column + i;
                    if (i.equals(0)) {
                        dynamicColumns.put(weeksColumn, classRoom.getName());
                    } else {
                        List<SchedulingGrade> mapGradeList = new ArrayList<>();
                        String gradeName = "";
                        for (SchedulingGrade grade : gradeList) {
                            if (grade.getClassRoomId() != null && classRoom.getId() != null && grade.getWeekDates() != null) {
                                if (grade.getClassRoomId().equals(classRoom.getId()) && schoolTime.equals(grade.getSchoolTime())) {
                                    //Map<String,Object> gradeMap = new HashMap<>();
                                    //gradeMap.put("grade",grade);
                                    mapGradeList.add(grade);
                                    //gradeName += grade.getName()+",";
                                }
                            }
                        }
                        dynamicColumns.put(weeksColumn, mapGradeList);
                        //dynamicColumns.put(weeksColumn,gradeName);
                    }
                    i++;
                }
                mapList.add(dynamicColumns);
            }


            Map<String, Object> map = new HashMap<>();
            map.put("headList", schoolTimeList);
            map.put("mapList", mapList);
            rsMapList.add(map);
        }
        return rsMapList;
    }

//    @Override
//    public List arrangingExcels() {
//        return Collections.singletonList(arrangingExcels);
//    }


    /**
     * 周内
     *
     * @param yearPart
     * @param quarterNum
     * @param schoolId
     * @return
     */
    @Override
    public List<String> weekdayExcel(Integer yearPart, Integer quarterNum, Long schoolId, Integer subjectsId,Integer lessonType,Integer sourseLeve, Long adminId) {
        /**
         * 班级上课时间
         */
        List<SchedulingGrade> gradeList = iGradeService.getGradeListForScheduling(schoolId, subjectsId, yearPart, quarterNum, null,lessonType,sourseLeve,adminId);

        /**
         * 教室
         */
        List<ClassRoom> classRoomList = iClassRoomService.getGradeClassRoomList(schoolId, yearPart, quarterNum,lessonType,sourseLeve,adminId);

        String[] weeks = {"", "周一", "周二", "周三", "周四", "周五"};
        String column = "column";

        Map<String, Object> dynamicColumns = new LinkedHashMap<>();
        Integer i = 0;
        List<Map<String, Object>> mapList = new ArrayList<>();

        for (ClassRoom classRoom : classRoomList) {
            dynamicColumns = new LinkedHashMap<>();
            i = 0;
            for (String weeksName : weeks) {
                String weeksColumn = column + i;
                if (i.equals(0)) {
                    dynamicColumns.put(weeksColumn, classRoom.getName());

                } else {
                    List<SchedulingGrade> mapGradeList = new ArrayList<>();
                    for (SchedulingGrade grade : gradeList) {
                        if (grade.getClassRoomId() != null && classRoom.getId() != null && grade.getWeekDates() != null) {
                            if (grade.getClassRoomId().equals(classRoom.getId()) && grade.getWeekDates().equals(i.toString())) {
                                mapGradeList.add(grade);
                                weeks[0] = grade.getSchoolTime();
                            }
                        }
                    }
                    dynamicColumns.put(weeksColumn, mapGradeList);
                }
                i++;
            }
            mapList.add(dynamicColumns);

        }
        java.util.ArrayList<String> weekList = new ArrayList<>(Arrays.asList(weeks));
        weekList.stream().forEach(System.out::println);

        return weekList;

    }
}
